package huffman;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.util.Hashtable;
import commons.Utility;

public class HuffmanArchiver {

	/**
	 * @param args
	 * @throws Exception
	 * @throws IOException
	 * @throws UnsupportedEncodingException
	 */
	static Huffman h = new Huffman();

	/**
	 * Decompress the given file
	 * 
	 * @param f
	 * @throws UnsupportedEncodingException
	 * @throws IOException
	 * @throws Exception
	 */
	public static void decompress(File f) throws UnsupportedEncodingException,
			IOException, Exception {
	// 	String[] files = f.list();
		String filePath = "";

		// determine file to decompress
		//for (String file : files) {
		//	if (file.lastIndexOf(".cm") == -1) {
	//			filePath = file ;
		//		break;
		//	}
		//}
		FileInputStream fis = new FileInputStream(f);
		ObjectInputStream ois = new ObjectInputStream(fis);
		Hashtable<String, String> table = (Hashtable<String, String>) ois
				.readObject();
		byte[] b = (byte[]) ois.readObject();

		BigInteger bi = new BigInteger(b);
		String nullen = "";
		for (int i = 0; i < bi.toString(2).length() % 8; i++) {
			nullen += "0";
		}

		h.setHuffmanTable(table);

		String klar = h.Decompress(nullen + bi.toString(2));
		FileOutputStream fos;

		try {
			// extract to parent directory
			File file = new File(f.getAbsolutePath() + ".dec");
			fos = new FileOutputStream(file);
			fos.write(klar.getBytes());

		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Compress the given file
	 * 
	 * @param f
	 * @throws UnsupportedEncodingException
	 * @throws IOException
	 * @throws Exception
	 */
	public static void compress(File f) throws UnsupportedEncodingException,
			IOException, Exception {
		try {
			// Datei lesen, -> string
			byte[] readBytes = Utility.FileAsByteArrayExample(f);
			String s = Utility.ByteArrayToString(readBytes);

			// Compress
			String compressedString = h.Compress(s);
			// TODO: store hashtable into the same source
			Hashtable<String, String> table = h.getHuffmanTable();

			BigInteger bi = new BigInteger(compressedString, 2);
			FileOutputStream fos;

			File archivedFile = new File(f.getAbsolutePath() + ".ha");
			fos = new FileOutputStream(archivedFile);
			ObjectOutputStream owr = new ObjectOutputStream(fos);
			owr.writeObject(table);
			owr.writeObject(bi.toByteArray());
			owr.flush();
			owr.close();
			fos.close();

		} catch (FileNotFoundException notFound) {
			System.out.println("Specified file not found!");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
